package com.bluefox.uac.filter;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.bluefox.common.web.exception.CustomRuntimeException;
import com.bluefox.common.webauth.filter.FilterProcessUrlRequestMatcher;
import com.bluefox.uac.model.LoginBean;
import com.bluefox.uac.security.CustomAuthenticationToken;
import com.bluefox.uac.service.AuthenticationService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 账户登录认证过滤器
 *
 * @author SF  创建时间: 2019/12/4 13:50
 */
public class AccountAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
    private static final Logger log = LoggerFactory.getLogger(AccountAuthenticationFilter.class);

    @Autowired
    private AuthenticationService authenticationService;

    private boolean postOnly = false;

    public AccountAuthenticationFilter() {
        super(new FilterProcessUrlRequestMatcher("/w/login"));
        super.setAuthenticationSuccessHandler(new AuthenticationSuccessHandler());
        super.setAuthenticationFailureHandler(new DefaultAuthenticationFailureHandler());
    }


    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse httpServletResponse) throws AuthenticationException, IOException, ServletException {
        if (AccountAuthenticationFilter.log.isInfoEnabled()) {
            AccountAuthenticationFilter.log.info("用户登录开始, headers: {}", request.getHeader("Tenant"));
        }
        if (this.postOnly && !request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }

        final LoginBean authRequest = this.obtainAuthRequest(request);
        final CustomAuthenticationToken token = this.authenticationService.clientUserLogin(authRequest);

        return token;
    }

    protected LoginBean obtainAuthRequest(final HttpServletRequest request) {
        if (request.getMethod().equals(HttpMethod.GET.name())) {
            final LoginBean authToken = new LoginBean();
            authToken.setUsername(request.getParameter("username"));
            authToken.setPassword(request.getParameter("password"));
            return authToken;
        }
        try {
            StringBuffer sb = new StringBuffer();
            final InputStreamReader reader = new InputStreamReader(request.getInputStream());
            BufferedReader br = new BufferedReader(reader);
            String s = "";
            while ((s = br.readLine()) != null) {
                sb.append(s);
            }
            String str = sb.toString();
            System.out.println(str);
            JSONObject jsonObject = JSONUtil.parseObj(str);
            final LoginBean loginParams = new LoginBean();
            loginParams.setUsername(jsonObject.getStr("username"));
            loginParams.setPassword(jsonObject.getStr("password"));

            System.out.println(loginParams);
            return loginParams;
        } catch (final IOException e) {
            AccountAuthenticationFilter.log.error("解析登录请求参数失败", e);
            throw new CustomRuntimeException("400", "无效的登录信息");
        }
    }

    public void setPostOnly(final boolean postOnly) {
        this.postOnly = postOnly;
    }

}
